package com.xuecheng.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.base.exception.CommonError;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.base.model.PageResult;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.learning.feignclient.ContentServiceClient;
import com.xuecheng.learning.mapper.XcChooseCourseMapper;
import com.xuecheng.learning.mapper.XcCourseTablesMapper;
import com.xuecheng.learning.model.dto.MyCourseTableItemDto;
import com.xuecheng.learning.model.dto.MyCourseTableParams;
import com.xuecheng.learning.model.dto.XcChooseCourseDto;
import com.xuecheng.learning.model.dto.XcCourseTablesDto;
import com.xuecheng.learning.model.po.XcChooseCourse;
import com.xuecheng.learning.model.po.XcCourseTables;
import com.xuecheng.learning.service.MyCourseTablesService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author Mr.M
 * @version 1.0
 * @description TODO
 * @date 2022/10/2 16:12
 */
@Slf4j
@Service
public class MyCourseTablesServiceImpl implements MyCourseTablesService {

    //选课记录表的mapper
    @Autowired
    XcChooseCourseMapper xcChooseCourseMapper;

    //我的课程表mapper
    @Autowired
    XcCourseTablesMapper xcCourseTablesMapper;

    @Autowired
    ContentServiceClient contentServiceClient;

    @Autowired
    MyCourseTablesServiceImpl myCourseTablesService;

    @Autowired
    XcCourseTablesMapper courseTablesMapper;

    @Override
    public XcChooseCourseDto addChooseCourse(String userId, Long courseId) {

        //调用内容管理服务查询课程信息
        CoursePublish coursepublish = contentServiceClient.getCoursepublish(courseId);
        if (coursepublish == null) {
            XueChengPlusException.cast("课程信息不存在");
        }
        Long id = coursepublish.getId();
        if (id == null) {
            XueChengPlusException.cast(CommonError.UNKOWN_ERROR);
        }
        //课程收费标准
        String charge = coursepublish.getCharge();

        XcChooseCourse xcChooseCourse = null;
        if (charge.equals("201001")) {
            //添加收费课程，只能添加到选课记录表
            xcChooseCourse = myCourseTablesService.addChargeCoruse(userId, coursepublish);
        } else {
            //添加免费课程，添加到选课记录表，添加到我的课程表
            xcChooseCourse = myCourseTablesService.addFreeCoruse(userId, coursepublish);
        }

        //构造返回对象，获取用户对该课程的学习资格
        XcChooseCourseDto xcChooseCourseDto = new XcChooseCourseDto();
        BeanUtils.copyProperties(xcChooseCourse, xcChooseCourseDto);
        //获取学习资格
        XcCourseTablesDto xcCourseTablesDto = getLeanringStatus(userId, courseId);
        xcChooseCourseDto.setLearnStatus(xcCourseTablesDto.getLearnStatus());
        return xcChooseCourseDto;
    }


    /**
     * @param userId   用户id
     * @param courseId 课程id
     * @return XcCourseTablesDto 学习资格状态
     * [{"code":"702001","desc":"正常学习"},
     * {"code":"702002","desc":"没有选课或选课后没有支付"},
     * {"code":"702003","desc":"已过期需要申请续期或重新支付"}]
     * @description 判断学习资格
     */
    public XcCourseTablesDto getLeanringStatus(String userId, Long courseId) {
        XcCourseTables xcCourseTables = getXcCourseTables(userId, courseId);
        if (xcCourseTables == null) {
            XcCourseTablesDto xcCourseTablesDto = new XcCourseTablesDto();
            xcCourseTablesDto.setLearnStatus("702002");//没有学习资格
            return xcCourseTablesDto;
        }
        XcCourseTablesDto xcCourseTablesDto = new XcCourseTablesDto();
        BeanUtils.copyProperties(xcCourseTables, xcCourseTablesDto);
        //判断课程是否过期,true过期，false未过期
        LocalDateTime validtimeEnd = xcCourseTables.getValidtimeEnd();
        boolean isExpires = validtimeEnd.isBefore(LocalDateTime.now());
        if (!isExpires) {
            //正常学习
            xcCourseTablesDto.setLearnStatus("702001");
            return xcCourseTablesDto;
        } else {
            //已过期
            xcCourseTablesDto.setLearnStatus("702003");
            return xcCourseTablesDto;
        }

    }

    @Override
    public boolean saveChooseCourseStauts(String choosecourseId) {

        //根据choosecourseId查询选课记录
        XcChooseCourse xcChooseCourse = xcChooseCourseMapper.selectById(choosecourseId);
        if (xcChooseCourse != null) {
            String status = xcChooseCourse.getStatus();
            if ("701001".equals(status)) {
                //添加到课程表
                addCourseTabls(xcChooseCourse);
                return true;
            }
            if ("701002".equals(status)) {//待支付
                //更新为选课成功
                xcChooseCourse.setStatus("701001");
                int update = xcChooseCourseMapper.updateById(xcChooseCourse);
                //添加到课程表
                addCourseTabls(xcChooseCourse);
                if (update > 0) {
                    log.debug("收到支付结果通知处理成功,选课记录:{}", xcChooseCourse);
                    return true;
                } else {
                    log.debug("收到支付结果通知处理失败,选课记录:{}", xcChooseCourse);
                    return false;
                }
            } else {
                log.debug("收到支付结果通知已经处理,选课记录:{}", xcChooseCourse);
                return true;
            }
        } else {
            log.debug("收到支付结果通知没有查询到关联的选课记录,choosecourseId:{}", choosecourseId);
        }
        return false;
    }


    /**
     * @param userId   用户id
     * @param courseId 课程id
     * @return com.xuecheng.learning.model.po.XcCourseTables
     * @description 根据课程和用户查询我的课程表中某一门课程
     */
    public XcCourseTables getXcCourseTables(String userId, Long courseId) {
        XcCourseTables xcCourseTables = xcCourseTablesMapper.selectOne(new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId, userId).eq(XcCourseTables::getCourseId, courseId));
        return xcCourseTables;

    }


    //添加免费课程,免费课程加入选课记录表、我的课程表
    @Transactional
    public XcChooseCourse addFreeCoruse(String userId, CoursePublish coursepublish) {
        //查询选课记录表是否存在免费的且选课成功的订单
        //课程id
        Long courseId = coursepublish.getId();
        //校验该课程是否添加到了选课记录表，如果已添加则直接返回
        LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper = queryWrapper.eq(XcChooseCourse::getUserId, userId)
                .eq(XcChooseCourse::getCourseId, courseId)
                .eq(XcChooseCourse::getOrderType, "700001")//免费订单
                .eq(XcChooseCourse::getStatus, "701001");//选课成功
        List<XcChooseCourse> xcChooseCourses = xcChooseCourseMapper.selectList(queryWrapper);
        if (xcChooseCourses != null && xcChooseCourses.size() > 0) {
            return xcChooseCourses.get(0);
        }
        //添加选课记录信息
        XcChooseCourse xcChooseCourse = new XcChooseCourse();
        xcChooseCourse.setCourseId(courseId);
        xcChooseCourse.setCourseName(coursepublish.getName());
        xcChooseCourse.setCoursePrice(0f);//免费课程价格为0
        xcChooseCourse.setUserId(userId);
        xcChooseCourse.setCompanyId(coursepublish.getCompanyId());
        xcChooseCourse.setOrderType("700001");//免费课程
        xcChooseCourse.setCreateDate(LocalDateTime.now());
        xcChooseCourse.setStatus("701001");//选课成功

//        xcChooseCourse.setValidDays(365);//免费课程默认365
        xcChooseCourse.setValidDays(coursepublish.getValidDays());//有效期（天）
        xcChooseCourse.setValidtimeStart(LocalDateTime.now());//开始服务时间
//        xcChooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365));//结束服务时间
        xcChooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(coursepublish.getValidDays()));//截至日期
        xcChooseCourseMapper.insert(xcChooseCourse);
        //添加到我的课程表
        addCourseTabls(xcChooseCourse);
        return xcChooseCourse;

    }

    /**
     * @param xcChooseCourse 选课记录
     * @return com.xuecheng.learning.model.po.XcCourseTables
     * @description 添加到我的课程表
     */
    @Transactional
    public XcCourseTables addCourseTabls(XcChooseCourse xcChooseCourse) {
        //校验该课程表在我的课程表中是否存在
        //课程id
        Long courseId = xcChooseCourse.getCourseId();
        //用户id
        String userId = xcChooseCourse.getUserId();
        //选课记录完成且未过期可以添加课程到课程表
        String status = xcChooseCourse.getStatus();
        if (!"701001".equals(status)) {
            XueChengPlusException.cast("选课记录未完成，无法添加到课程表");
        }
        //查询我的课程表
        XcCourseTables xcCourseTables = getXcCourseTables(userId, courseId);
        if (xcCourseTables != null) {
            LocalDateTime validtimeEnd = xcChooseCourse.getValidtimeEnd();
            if (xcCourseTables.getValidtimeEnd().isAfter(validtimeEnd)) {
                //如果我的课程表中的过期时间比新订单的过期时间靠后，不用更新课程表。
                return xcCourseTables;
            } else {
                //更新我的课程表
                xcCourseTables.setChooseCourseId(xcChooseCourse.getId());
                xcCourseTables.setUpdateDate(LocalDateTime.now());
                xcCourseTables.setValidtimeStart(xcChooseCourse.getValidtimeStart());
                xcCourseTables.setValidtimeEnd(xcChooseCourse.getValidtimeStart());
                xcCourseTables.setCourseType(xcChooseCourse.getOrderType());
                xcCourseTablesMapper.updateById(xcCourseTables);
                return xcCourseTables;
            }
        }
        //向我的课程表添加记录
        XcCourseTables xcCourseTablesNew = new XcCourseTables();
        //选课记录id
        Long xcChooseCourseId = xcChooseCourse.getId();
        xcCourseTablesNew.setChooseCourseId(xcChooseCourseId);
        xcCourseTablesNew.setUserId(xcChooseCourse.getUserId());
        xcCourseTablesNew.setCourseId(xcChooseCourse.getCourseId());
        xcCourseTablesNew.setCompanyId(xcChooseCourse.getCompanyId());
        xcCourseTablesNew.setCourseName(xcChooseCourse.getCourseName());
        xcCourseTablesNew.setCreateDate(LocalDateTime.now());
        xcCourseTablesNew.setValidtimeStart(xcChooseCourse.getValidtimeStart());
        xcCourseTablesNew.setValidtimeEnd(xcChooseCourse.getValidtimeEnd());
        xcCourseTablesNew.setCourseType(xcChooseCourse.getOrderType());
        xcCourseTablesMapper.insert(xcCourseTablesNew);

        return xcCourseTablesNew;

    }

    //添加收费课程
    @Transactional
    public XcChooseCourse addChargeCoruse(String userId, CoursePublish coursepublish) {

        //如果存在待支付记录直接返回
        LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper = queryWrapper.eq(XcChooseCourse::getUserId, userId)
                .eq(XcChooseCourse::getCourseId, coursepublish.getId())
                .eq(XcChooseCourse::getOrderType, "700002")//收费订单
                .eq(XcChooseCourse::getStatus, "701002");//待支付
        List<XcChooseCourse> xcChooseCourses = xcChooseCourseMapper.selectList(queryWrapper);
        if (xcChooseCourses != null && xcChooseCourses.size() > 0) {
            return xcChooseCourses.get(0);
        }

        //向选课记录添加记录
        XcChooseCourse xcChooseCourse = new XcChooseCourse();
        xcChooseCourse.setCourseId(coursepublish.getId());
        xcChooseCourse.setCourseName(coursepublish.getName());
        xcChooseCourse.setCoursePrice(coursepublish.getPrice());//免费课程价格为0
        xcChooseCourse.setUserId(userId);
        xcChooseCourse.setCompanyId(coursepublish.getCompanyId());
        xcChooseCourse.setOrderType("700002");//收费课程
        xcChooseCourse.setCreateDate(LocalDateTime.now());
        xcChooseCourse.setStatus("701002");//待支付
        xcChooseCourse.setValidDays(coursepublish.getValidDays());
        xcChooseCourse.setValidtimeStart(LocalDateTime.now());
        xcChooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(coursepublish.getValidDays()));
        xcChooseCourseMapper.insert(xcChooseCourse);

        return xcChooseCourse;
    }

    public PageResult<MyCourseTableItemDto> mycourestabls(MyCourseTableParams params) {

        int page = params.getPage();
        int size = params.getSize();
        int startIndex = (page - 1) * size;
        params.setStartIndex(startIndex);

        List<MyCourseTableItemDto> myCourseTableItemDtos = xcCourseTablesMapper.myCourseTables(params);
        int total = xcCourseTablesMapper.myCourseTablesCount(params);


        PageResult pageResult = new PageResult(myCourseTableItemDtos, total, page, size);
        pageResult.setItems(myCourseTableItemDtos);
        pageResult.setCounts(total);
        pageResult.setPage(page);
        pageResult.setPageSize(size);
        return pageResult;

    }

}
